package xyz.wadewhy.basicstest.juc;

import lombok.extern.slf4j.Slf4j;

/**
 * @ClassName ThreadDemoV2
 * @Description 业务用途
 * @Author zhongzihao
 * @Date 2021/12/27 9:48 下午
 * @Version 1.0
 **/
@Slf4j(topic = "c.Test")
public class ThreadDemoV2 {
    private static final int NUM = 50000;
    private static int count = 0;
    private static int count2 = 0;
    private static final Object LOCK = new Object();

    public static void main(String[] args) throws InterruptedException {
        concurrentDemo();
        synchronizedDemo();
    }

    /**
     * 并发临界情况
     * 由于并发原因，最终数目不一定为0，也有可能为0
     */
    public static void concurrentDemo() throws InterruptedException {
        Thread thread = new Thread(() -> {
            for (int i = 0; i < NUM; i++) {
                count++;
            }
        }, "线程1");
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < NUM; i++) {
                count--;
            }
        }, "线程2");
        thread.start();
        thread1.start();
        //主线程等待thread， thread1 再打印debug日志
        thread.join();
        thread1.join();
        log.debug("{}", count);
    }

    /**
     * 使用synchronized 加锁处理并发
     * 1.synchronized加锁，假设线程1拿到锁，及时在时间片内未完成业务，也不会放开锁
     * 这时线程2只能等待，知道线程1锁释放，线程2竞争拿到锁
     */
    public static void synchronizedDemo() throws InterruptedException {

        Thread thread = new Thread(() -> {
            for (int i = 0; i < NUM; i++) {
                synchronized (LOCK) {
                    count2++;
                }
            }
        }, "线程1");
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < NUM; i++) {
                synchronized (LOCK) {
                    count2--;
                }
            }
        }, "线程2");
        thread.start();
        thread1.start();
        //主线程等待thread， thread1 再打印debug日志
        thread.join();
        thread1.join();
        log.debug("{}", count2);
    }
}
